(function() {
  var methods = {
    gvmap: function(locale) { 
        if(!GBrowserIsCompatible()){
            alert('Your browser is not compatible with Google Maps')
            return
        }
        this.each(function(index, obj){
            obj.map = new GMap2(obj)
            obj.geocoder = new GClientGeocoder()
            if(typeof(locale) != "undefined"){
                obj.locale = locale
            } else {
                obj.locale = "pt_BR"
            }
        })
        return this
    },
    satteliteMap: function(){
        this.each(function(index, obj){
            obj.map.setMapType(G_SATELLITE_MAP)
        })
        return this
    },
    normalMap: function(){
        this.each(function(index, obj){
            obj.map.setMapType(G_NORMAL_MAP)
        })
        return this
    },
    hybridMap: function(){
        this.each(function(index, obj){
            obj.map.setMapType(G_HYBRID_MAP)
        })
        return this
    },
    setMapType: function(mapType){
        if(mapType == "satellite"){
            this.satteliteMap()
        } else if (mapType == "hybrid"){
            this.hybridMap()
        } else {
            this.normalMap()
        }
    },
    getMapType: function(){
        this.each(function(index, obj){
            var mapType = jQuery(obj).attr('mapType')
            if(mapType){
                jQuery(obj).setMapType(mapType)
            }
        })
    },
    showMap: function() {
        this.each(function(index, obj){
            if($(obj).attr('query')){
                $(obj).query($(obj).attr('query'))
            } else if($(obj).attr('from') && $(obj).attr('to')){
                $(obj).route()
            } else {
                $(obj).centerMap()
            }
        })
    },
    latitude: function(place){
        this.each(function(index, obj){
            obj.latitude = place
        })
        return this
    },
    longitude: function(place){
        this.each(function(index, obj){
            obj.longitude = place
        })
        return this
    },
    zoom: function(number){
        this.each(function(index, obj){
            obj.zoom = number
        })
        return this
    },
    mapControl: function(level){
        var control = null
        if(typeof(level) != "undefined"){
            if(level == "large"){
                control = new GLargeMapControl()
            } else if(level == "small") {
                control = new GSmallMapControl()
            }
        }
        if(control == null) control = new GSmallMapControl()
        this.each(function(index, obj){
            obj.map.addControl(control)
        })
        return this
    },
    zoomControl: function(){
        this.each(function(index, obj){
            obj.map.addControl(new GSmallZoomControl())
        })
        return this
    },
    from: function(place){
        this.each(function(index, obj){
            obj.from = place
        })
        return this
    },
    to: function(place){
        this.each(function(index, obj){
            obj.to = place
        })
        return this
    },
    centerMap: function(){
        this.each(function(index, obj){
            var latitude, longitude
            if(jQuery(obj).attr('latitude') && jQuery(obj).attr('longitude')){
                latitude = Number(jQuery(obj).attr('latitude'))
                longitude = Number(jQuery(obj).attr('longitude'))
            } else{
                latitude = -12.726084296948184
                longitude = -54.052734375
            }
            var zoom = jQuery(obj).attr('zoom') ? Number(jQuery(obj).attr('zoom')) : 4

            jQuery(obj).getMapType()

            obj.map.setCenter(new GLatLng(latitude, longitude), zoom)
        })
    },
    query: function(address, gvmark){
          this.each(function(index, obj){
                obj.geocoder.getLatLng(address, function(point){
				    if (!point) {
					    alert(address + " not found!")
                        return
				    }

                    jQuery(obj).getMapType()

                    var zoom = jQuery(obj).attr('zoom') ? Number(jQuery(obj).attr('zoom')) : 4
                    obj.map.setCenter(point, zoom)
                    var mark
                    if(typeof(gvmark) != "undefined"){
                        var opt = {icon: gvmark.ico, draggable: gvmark.draggable}
                        mark = new GMarker(point, opt)
                        mark.gvmark = gvmark
                        if(gvmark.draggable){
                            GEvent.addListener(mark, "dragstart", function(){
                                obj.map.closeInfoWindow()
                            })
                            GEvent.addListener(mark, "dragend", function(){
                                mark.openInfoWindowHtml(mark.gvmark.html)
                            })
                        }
                        GEvent.addListener(mark, "click", function(){
                            mark.openInfoWindowHtml(mark.gvmark.html)
                        })
                    } else {
                        mark = new GMarker(point)
                        GEvent.addListener(mark, "click", function(){
                            mark.openInfoWindowHtml(address)
                        })
                    }                    
                    obj.map.addOverlay(mark)
			    })
          })
          return this
    },
    route: function(selector){
        this.each(function(index, obj){
            $(obj).clearMarker()
            jQuery(obj).getMapType()
            var directions
            if(typeof(selector) != "undefined"){
                jQuery(selector).html('')
                directions = new GDirections(obj.map, jQuery(selector)[0])
            } else {
                directions = new GDirections(obj.map)
            }
            GEvent.addListener(directions, "error", function(){ 
                if(directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS){
                    alert("Address not found")
                } else if (directions.getStatus().code == G_GEO_MISSING_QUERY){
                    alert("Please fill in all fields")
                }
            })
            var from = jQuery(obj).attr('from')
            var to = jQuery(obj).attr('to')
            directions.load("from: " + from + " to: " + to, {locale: obj.locale})
        })
    },
    add: function(lat, lng, gvmark){
        this.each(function(index, obj){
            var point = new GLatLng(lat, lng)
            var mark
            if(typeof(gvmark) != "undefined"){
                var opt = {icon: gvmark.ico, draggable: gvmark.draggable}
                mark = new GMarker(point, opt)
                mark.gvmark = gvmark
                if(gvmark.draggable){
                    GEvent.addListener(mark, "dragstart", function(){
                        obj.map.closeInfoWindow()
                    })
                    GEvent.addListener(mark, "dragend", function(){
                        mark.openInfoWindowHtml(mark.gvmark.html)
                    })
                }
                GEvent.addListener(mark, "click", function(){
                    mark.openInfoWindowHtml(mark.gvmark.html)
                })
            } else {
                mark = new GMarker(point)
            }
            obj.map.addOverlay(mark)
        })
        return this
    },
    addAddress: function(addr, gvmark){
        alert('Not implemented')
    },
    clearMarker: function(){
        this.each(function(index, obj){
            obj.map.clearOverlays()
        })
    }
  }
  jQuery.gvmarker = function(html, draggable, ico){
        var opts = {
            html: html,
            draggable: (typeof(draggable) != "undefined") ? draggable : false
        }
        if(typeof(ico) != "undefined"){
            var icon = new GIcon(G_DEFAULT_ICON)
            icon.image = ico;
			icon.shadowSize.width = 0
			icon.shadowSize.height = 0
            opts['ico'] = icon
        }
        return opts
    }
  jQuery.each(methods, function(i) {
    jQuery.fn[i] = this;
  })
})()


